package com.eastdigit.bpm.cmd;

import java.io.Serializable;

import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;

/**
 * <p>Project: eastdigit-bpm </p>
 * <p>Description:  删除流程</p>
 *
 * @author jun
 * @date 2016-5-10
 */
public class DeleteProcessInstanceAndHisCmd implements Command<Void>,
		Serializable {

	private static final long serialVersionUID = 1L;
	protected String processInstanceId;
	protected String deleteReason;

	public DeleteProcessInstanceAndHisCmd(String processInstanceId,
			String deleteReason) {
		this.processInstanceId = processInstanceId;
		this.deleteReason = deleteReason;
	}

	public Void execute(CommandContext commandContext) {
		if (processInstanceId == null) {
			throw new ActivitiIllegalArgumentException(
					"processInstanceId is null");
		}

		// fill default reason if none provided
		if (deleteReason == null) {
			deleteReason = "ACTIVITI_DELETED";
		}

		if (commandContext.getProcessEngineConfiguration().getEventDispatcher()
				.isEnabled()) {
			commandContext
					.getProcessEngineConfiguration()
					.getEventDispatcher()
					.dispatchEvent(
							ActivitiEventBuilder.createCancelledEvent(
									this.processInstanceId,
									this.processInstanceId, null, deleteReason));
		}

		ExecutionEntity execution = commandContext.getExecutionEntityManager()
				.findExecutionById(processInstanceId);
		if (execution != null) {
			deleteProcessInstanceCascade(commandContext, execution,
					deleteReason);
		} else {
			commandContext.getHistoricProcessInstanceEntityManager()
					.deleteHistoricProcessInstanceById(processInstanceId);
		}

		return null;
	}

	private void deleteProcessInstanceCascade(CommandContext commandContext,
			ExecutionEntity execution, String deleteReason) {
		for (ExecutionEntity subExecutionEntity : execution.getExecutions()) {
			if (subExecutionEntity.getSubProcessInstance() != null) {
				deleteProcessInstanceCascade(commandContext, subExecutionEntity
						.getSubProcessInstance(), deleteReason);
			}
		}

		commandContext.getTaskEntityManager().deleteTasksByProcessInstanceId(
				execution.getId(), deleteReason, true);

		execution.deleteCascade(deleteReason);

		commandContext.getHistoricProcessInstanceEntityManager()
				.deleteHistoricProcessInstanceById(execution.getId());

	}

}
